﻿/* 2011/11/19 */
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;

namespace Cosmos.Shortcuts
{
    /// <summary>
    /// Executes a operation by giving shortcut actions.
    /// </summary>
    public class ShortcutExecutant
    {
        protected ShortcutOperation _shortcutOperation;
        protected List<IShortcutAction> _shortcutActions;

        /// <summary>
        /// Initializes a default instance of ShortcutOperation.
        /// </summary>
        public ShortcutExecutant()
        {
            _shortcutActions = new List<IShortcutAction>(0);
        }

        /// <summary>
        /// Initializes a instance of ShortcutOperation.
        /// </summary>
        /// <param name="shortcutOperation">The invoked operation and its parameter.</param>
        /// <param name="shortcutActions">The shortcut actions.</param>
        public ShortcutExecutant(ShortcutOperation shortcutOperation, params IShortcutAction[] shortcutActions)
        {
            _shortcutOperation = shortcutOperation;
            if (shortcutActions != null)
            {
                _shortcutActions = new List<IShortcutAction>(shortcutActions.Length);
                foreach (IShortcutAction anAction in shortcutActions)
                {
                    _shortcutActions.Add(anAction);
                }
            }
            else
            {
                _shortcutActions = new List<IShortcutAction>(0);
            }
        }

        /// <summary>
        /// Initializes a instance of ShortcutExecutant by escape string.
        /// </summary>
        /// <param name="escapeString"></param>
        public ShortcutExecutant(string escapeString)
        {
            EscapeString = escapeString;
        }

        /// <summary>
        /// Generates the escape string of this ShortcutOperation which can be used to save the status.
        /// </summary>
        /// <returns></returns>
        protected string GenerateEscapeString()
        {
            /*
            string index;
            int keyNumber = (int)_shortcutKey.Key;
            int comberNumber = _shortcutKey.ComboNumber;
            int operationNumber = _operationParameter.Operation;
            index = String.Join(_KEY_OPERATION_SEPARATOR.ToString(), new string[] { keyNumber.ToString(), comberNumber.ToString(), operationNumber.ToString() });
            if (_operationParameter.Parameters != null)
                index = String.Concat(index, _KEY_OPERATION_SEPARATOR, _operationParameter.Parameters);
            return index;
            */
            StringWriter stringWriter = new StringWriter();
            
            XmlWriter xmlWriter = XmlWriter.Create(stringWriter, SimpleXmlSettings.WriterSettings);
            xmlWriter.WriteStartElement("Operation");
            xmlWriter.WriteString(_shortcutOperation.EscapeString);
            xmlWriter.WriteEndElement();

            xmlWriter.WriteStartElement("Actions");
            xmlWriter.WriteStartAttribute("Count");
            xmlWriter.WriteString(_shortcutActions.Count.ToString());
            xmlWriter.WriteEndAttribute();
            foreach (IShortcutAction aShortcutAction in _shortcutActions)
            {
                string actionType = null;
                if (aShortcutAction is KeyCombination)
                    actionType = "KeyCombination";
                else if (aShortcutAction is MouseGesture)
                    actionType = "MouseGesture";
                else
                    actionType = "Unknown";

                xmlWriter.WriteStartElement("Action");
                xmlWriter.WriteStartAttribute("Type");
                xmlWriter.WriteString(actionType);
                xmlWriter.WriteEndAttribute();
                xmlWriter.WriteString(aShortcutAction.EscapeString);
                xmlWriter.WriteEndElement();
            }            
            xmlWriter.WriteEndElement();

            xmlWriter.Flush();
            xmlWriter.Close();

            stringWriter.Flush();
            string result = stringWriter.ToString();
            stringWriter.Close();

            return result;
        }

        /// <summary>
        /// Update a instance of ShortcutOperation by escape string.
        /// </summary>
        /// <param name="escapeString">A escape string of ShortcutOperation.</param>
        protected void ParseEscapeString(string escapeString)
        {
            /*
            string[] informations = escapeString.Split(new char[] { _KEY_OPERATION_SEPARATOR });

            if (informations.Length < 3)
                return;

            int keyNumber = 0;
            Int32.TryParse(informations[0], out keyNumber);
            _shortcutKey = new KeyCombination((Keys)keyNumber);
            int comboNumber = 0;
            Int32.TryParse(informations[1], out comboNumber);
            _shortcutKey.ComboNumber = comboNumber;
            int operationNumber = 0;
            Int32.TryParse(informations[2], out operationNumber);
            _shortcutOperation = new ShortcutOperation(operationNumber);

            if (informations.Length == 4)
                _shortcutOperation.Parameters = informations[3];
            */

            StringReader stringReader = new StringReader(escapeString);
            XmlReader xmlReader = XmlReader.Create(stringReader, SimpleXmlSettings.ReaderSettings);

            xmlReader.ReadStartElement("Operation");
            _shortcutOperation.EscapeString = xmlReader.ReadContentAsString();
            xmlReader.ReadEndElement();

            int actionCount = Int32.Parse(xmlReader.GetAttribute("Count"));
            _shortcutActions = new List<IShortcutAction>(actionCount);
            if (actionCount > 0)
            {
                xmlReader.ReadStartElement("Actions");
                for (int i = 0; i < actionCount; i++)
                {
                    IShortcutAction theShortcutAction = null;
                    string actionType = xmlReader.GetAttribute("Type");
                    if (actionType.Equals("KeyCombination"))
                        theShortcutAction = new KeyCombination();
                    else if (actionType.Equals("MouseGesture"))
                        theShortcutAction = new MouseGesture();
                    else
                        theShortcutAction = null;

                    xmlReader.ReadStartElement("Action");
                    theShortcutAction.EscapeString = xmlReader.ReadContentAsString();
                    xmlReader.ReadEndElement();

                    _shortcutActions.Add(theShortcutAction);
                }
                xmlReader.ReadEndElement();
            }
            else
            {
                xmlReader.ReadStartElement("Actions");
            }            

            xmlReader.Close();
            stringReader.Close();
        }

        public string EscapeString
        {
            get { return GenerateEscapeString(); }
            set { ParseEscapeString(value); }
        }

        public int ActionCount
        {
            get 
            {
                if (_shortcutActions != null)
                    return _shortcutActions.Count;
                else
                    return 0;
            }
        }

        public ShortcutOperation ShortcutOperation
        {
            get { return _shortcutOperation; }
            set { _shortcutOperation = value; }
        }

        public int Operation
        {
            get { return _shortcutOperation.Operation; }
            set { _shortcutOperation.Operation = value; }
        }

        public string[] Arguments
        {
            get { return _shortcutOperation.Arguments; }
            set { _shortcutOperation.Arguments = value; }
        }
    }
}
